package com.fitness.front.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fitness.front.convertor.CourseReserveConvertor;
import com.fitness.front.exception.BizException;
import com.fitness.front.mapper.*;
import com.fitness.front.modal.course.entity.Course;
import com.fitness.front.modal.course.entity.CourseReserve;
import com.fitness.front.modal.course.entity.MemberCourse;
import com.fitness.front.modal.course.params.CourseReserveQueryParams;
import com.fitness.front.modal.course.vo.CourseReserveVO;
import com.fitness.front.modal.wallet.entity.MemberWallet;
import com.fitness.front.modal.wallet.entity.Recharge;
import com.fitness.front.service.ICourseReserveService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class CourseReserveServiceImpl extends ServiceImpl<CourseReserveMapper, CourseReserve> implements ICourseReserveService {

    private final CourseReserveConvertor courseReserveConvertor;
    private final CourseMapper courseMapper;
    private final MemberWalletMapper memberWalletMapper;
    private final RechargeMapper rechargeMapper;
    private final MemberCourseMapper memberCourseMapper;

    @Override
    public Page<CourseReserveVO> getCourseReservePage(Long memberId, CourseReserveQueryParams queryParams) {
        // 参数构建
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        Page<CourseReserve> page = new Page<>(pageNum, pageSize);

        // 查询数据
        Page<CourseReserve> coachBoPage = this.baseMapper.getCourseReservePage(page, memberId, queryParams);

        return courseReserveConvertor.entity2Vo(coachBoPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void reserveCourse(CourseReserve newCourseReserve) {
        this.save(newCourseReserve);
        Course course = courseMapper.selectById(newCourseReserve.getCourseId());
        course.setId(newCourseReserve.getCourseId());
        course.setReserveCnt(course.getReserveCnt() + 1);
        courseMapper.updateById(course);
        MemberCourse memberCourse = new MemberCourse();
        memberCourse.setCourseId(newCourseReserve.getCourseId());
        memberCourse.setMemberId(newCourseReserve.getMemberId());
        memberCourseMapper.insert(memberCourse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean payment(Long courseId,Long memberId, String memberName, Long amount,String comment) {
        QueryWrapper<MemberWallet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id", memberId);
        MemberWallet memberWallet = memberWalletMapper.selectOne(queryWrapper);
        if(memberWallet == null || memberWallet.getAmount() < amount){
            log.error("钱包余额小于待支付金额，支付失败");
            throw new BizException("钱包余额小于待支付金额，支付失败");
        }
        memberWallet.setAmount(memberWallet.getAmount() - amount);

        boolean result = memberWalletMapper.updateById(memberWallet) > 0;
        if(!result){
            result = this.lambdaUpdate().set(CourseReserve::getStatus,ICourseReserveService.COURSE_RESERVE_PAY_FAILURE)
                    .eq(CourseReserve::getCourseId,courseId)
                    .eq(CourseReserve::getMemberId,memberId).update();
            if(!result){
                throw new BizException("支付失败");
            }
            addRechargeRecord("payment",memberId,memberName,amount,comment);
            return result;
        }
        result = this.lambdaUpdate().set(CourseReserve::getStatus,ICourseReserveService.COURSE_RESERVE_PAY_SUCCESS)
                .eq(CourseReserve::getCourseId,courseId)
                .eq(CourseReserve::getMemberId,memberId).update();
        if(!result){
            throw new BizException("支付失败");
        }
        addRechargeRecord("payment",memberId,memberName,amount,comment);
        return result;
    }

    private void addRechargeRecord(String type,Long memberId,String memberName,Long amount,String comment) {
        Recharge recharge = new Recharge();
        recharge.setMemberId(memberId);
        recharge.setMemberName(memberName);
        recharge.setAmount(amount);
        recharge.setType(type);
        recharge.setRemark(comment);
        rechargeMapper.insert(recharge);
    }
}
